package com.cmcc.driver.ui.main

import android.Manifest
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.pm.PackageManager
import android.location.Location
import android.location.LocationManager
import android.media.MediaPlayer
import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.os.Looper
import android.provider.Settings
import android.speech.tts.TextToSpeech
import android.text.TextUtils
import android.util.Log
import android.view.View
import android.view.WindowManager
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.databinding.DataBindingUtil
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModelProviders
import com.alibaba.android.arouter.facade.annotation.Route
import com.alibaba.android.arouter.launcher.ARouter
import com.cmcc.driver.R
import com.cmcc.driver.broadcast.OrderReceiver
import com.cmcc.driver.broadcast.OrderStateChangeListener
import com.cmcc.driver.config.DriverPath
import com.cmcc.driver.data.entity.Coordinate
import com.cmcc.driver.databinding.ActivityDriverMainBinding
import com.cmcc.driver.ui.base.BasicActivity
import com.cmcc.driver.ui.dialog.AppAlertDialog
import com.cmcc.driver.ui.dialog.OrderGrabDialog
import com.cmcc.driver.ui.main.adapter.MainViewPagerAdapter
import com.cmcc.driver.ui.main.viewmodel.MainViewModel
import com.cmcc.driver.util.LocationUtil
import com.cmcc.shared.config.SharedConfig
import com.cmcc.shared.model.CoordinatesXY
import com.cmcc.shared.utils.L
import com.cmcc.shared.utils.clickWithTrigger
import com.cmcc.shared.utils.isOPenGps
import com.cmcc.shared.viewModel.SharedViewModel
import com.google.android.gms.location.*
import com.google.android.gms.maps.model.LatLng
import java.lang.Math.*
import java.lang.String.format
import java.util.*


/**
 * Author: jiangxin
 * Date: 2019/11/5
 * Description:
 */
@Route(path = DriverPath.DRIVER_MAIN)
class DriverMainActivity : BasicActivity(), OrderStateChangeListener, TextToSpeech.OnInitListener {

    private lateinit var fusedLocationClient: FusedLocationProviderClient
    private lateinit var locationRequest: LocationRequest
    private lateinit var locationCallback: LocationCallback

    private lateinit var binding: ActivityDriverMainBinding

    var viewModel: MainViewModel? = null
    private lateinit var appViewModel: SharedViewModel
    private var alertDialog: AppAlertDialog? = null


    private val fragments = mutableListOf<Fragment>()

    private val HKG = "HKG"
    private val YUE = "yue"
    private var mTextToSpeech: TextToSpeech? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN)

        fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)

        locationRequest = LocationRequest()
        locationRequest.interval = 5 * 1000L//请求时间间隔
        locationRequest.fastestInterval = 1500L//最快时间间隔
        locationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY

        locationCallback = object : LocationCallback() {
            override fun onLocationResult(locationResult: LocationResult?) {
                if (locationResult == null) return
                handleLocation(locationResult.lastLocation)
            }
        }

        checkGpsPermission()
        requestLocationPermission()

        getExtra(intent)
        //初始化 TextToSpeech   对象
        mTextToSpeech = TextToSpeech(this, this)
        // 设置音调，值越大声音越尖（女生），值越小则变成男声,1.0是常规
        mTextToSpeech?.setPitch(1.2f)
        // 设置语速
        mTextToSpeech?.setSpeechRate(0.9f)


    }

    private fun getExtra(intent: Intent) {
        val bundle = intent.extras
        if (bundle != null) {
            val orderId = bundle.getString("orderId")
            val status = bundle.getInt("status")
            if (status == 0) {//新订单
                orderId?.let { viewModel?.getOrderTemplate(it) }
                (fragments[1] as OrderReceiveFragment).updateUI()
            } else if (status == 7) {//拒单审核通过
                (fragments[1] as OrderReceiveFragment).updateUI()
                (fragments[2] as OrderInProgressFragment).updateUI()
            }
        }
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        intent?.let { getExtra(it) }
    }

    /**
     * 动态请求定位权限
     */
    private fun requestLocationPermission() {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
            requestLocationService()
            return
        }
        if (ContextCompat.checkSelfPermission(
                this,
                Manifest.permission.ACCESS_FINE_LOCATION
            ) == PackageManager.PERMISSION_GRANTED
        ) {
            requestLocationService()
        } else {
            requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 1)
        }
    }

    /**
     * 获取当前位置的回调方法
     */
    private fun handleLocation(currentLocation: Location) {
        val lat = currentLocation.latitude
        val lng = currentLocation.longitude
        if (lat != 0.0 && lng != 0.0) {
            val appointLoc = LatLng(lat, lng)

            LocationUtil.getInstance().setCurrentLoc(appointLoc)

            viewModel?.updateLocation(appointLoc)
            appViewModel.uploadBatch(coordinatesXY = CoordinatesXY(lng, lat))
        }
    }


    private fun stopLocationUpdate() {
        fusedLocationClient.removeLocationUpdates(locationCallback)
    }

    /**
     * 请求定位服务
     */
    private fun requestLocationService() {
        val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
        if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
            requestLocationUpdate()
        }
    }

    /**
     * 请求位置更新
     */
    private fun requestLocationUpdate() {
        fusedLocationClient.requestLocationUpdates(
            locationRequest,
            locationCallback,
            Looper.myLooper()
        )
    }

    override fun initialize(savedInstanceState: Bundle?) {
        binding = DataBindingUtil.setContentView(this, R.layout.activity_driver_main)

        binding.appbar.toolbar.setNavigationOnClickListener { finish() }
        binding.appbar.title.text = getString(R.string.driver_receive)
        binding.appbar.profile.visibility = View.VISIBLE
        binding.appbar.profile.clickWithTrigger {
            ARouter.getInstance().build(DriverPath.DRIVER_PROFILE).navigation()
        }

        fragments.add(OrderRecordFragment())
        fragments.add(OrderReceiveFragment())
//        fragments.add(OrderProgressFragment())
        fragments.add(OrderInProgressFragment())
        binding.viewPager.isUserInputEnabled = false
        binding.viewPager.adapter =
            MainViewPagerAdapter(fragments, this)

        viewModel = ViewModelProviders.of(this).get(MainViewModel::class.java)
        appViewModel = ViewModelProviders.of(this).get(SharedViewModel::class.java)


        viewModel?.getDriverInfo()
        viewModel?.requestCarInfo()
        viewModel?.queryOrderProgress()
        appViewModel.bookCountDownTimer(role = 2)
        alertDialog = AppAlertDialog(this)

    }

    /**
     * 检查是否开启GPS
     */
    private fun checkGpsPermission() {
        if (!isOPenGps(this)) {
            AppAlertDialog(this).setContent(getString(R.string.app_permission_request_message))
                .setNavigation(getString(R.string.reject), View.OnClickListener { finish() })
                .setPositive(getString(
                    R.string.agree
                ),
                    View.OnClickListener {
                        startActivityForResult(
                            Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS), REQUEST_CODE_GPS_CODE
                        )
                    }).show()
        }
    }

    /**
     * 初始化事件
     */
    override fun initEvent(savedInstanceState: Bundle?) {
        binding.layoutTab.groupTab.setOnCheckedChangeListener { _, checkedId ->
            run {
                selectPage(checkedId)
            }
        }
        //设置默认的事件
        binding.layoutTab.groupTab.check(R.id.order_receive)
        binding.viewPager.currentItem = 1
    }

    override fun initObserver(savedInstanceState: Bundle?) {
        appViewModel.isShowBookOver.observe(this, Observer { pair ->
            if (pair.second) {
                alertDialog?.dismiss()
                AppAlertDialog(this).setContent(getString(R.string.book_time_over_driver))
                    .setNavigation(getString(R.string.see_order),
                        View.OnClickListener {
                            ARouter.getInstance().build(DriverPath.ORDER_IN_PROGRESS_DETAIL)
                                .withString("orderId", pair.first).navigation()
                        })
                    .setPositive(
                        getString(com.cmcc.shared.R.string.contact_cuservice),
                        View.OnClickListener {
                            val data = Uri.parse("tel:85262325253")
                            val intent = Intent(Intent.ACTION_DIAL, data)
                            startActivity(intent)
                        }
                    ).show()
            }
        })

        viewModel?.driverInfo?.observe(this, Observer {
            if (it?.headPortraitAddress != null) {
                binding.avatarUrl = it.headPortraitAddress
            }
        })

        viewModel?.orderTemplate?.observe(this, Observer {
            if (isSee) {
                val dialog = OrderGrabDialog.newFragment(it)
                try {
                    dialog.show(
                        (this as AppCompatActivity).supportFragmentManager,
                        "OrderGrabDialog"
                    )
                } catch (e: Exception) {

                }
            }

            Log.e(TAG, "-----------------")
            var text =
                "订单来啦，" + getDistance(it.startCoordinates) + "，从" + it.startAddress + "到" + it.endAddress
            Log.e(TAG, text + "-----------------")
            //在这播报
            //司机收到订单，在这里进行语音播报
            speakText(text);

        })
        viewModel?.order?.observe(this, Observer { order ->
            //            if (order == null) {
//                currentPage(R.id.order_receive)
//                AppAlertDialog(this).setContent(getString(R.string.no_order_alert_dialog))
//                    .setNavigation("", null, false)
//                    .setPositive(getString(R.string.make_sure), View.OnClickListener {
//
//                    }).show()
//            } else {
//                binding.viewPager.currentItem = 2
//                (fragments[2] as OrderInProgressFragment).updateUI()
//                binding.appbar.title.text = getString(R.string.driver_main_title)
//            }

            if (order != null && order.status != 0) {
                alertDialog?.let {
                    it.setContent(getString(R.string.has_order_alert_dialog))
                        .setNavigation("", null, false)
                        .setPositive(getString(R.string.make_sure), View.OnClickListener {
                            ARouter.getInstance().build(DriverPath.ORDER_IN_PROGRESS_DETAIL)
                                .withString("orderId", order.id)
                                .navigation()
                        }).show()
                }
            }
        })
    }

    /**
     * 获取司机到乘客的距离
     * 格式化成   距您X公里
     */
    private fun getDistance(startCoordinates: Coordinate?): String? {
        val endLat = startCoordinates?.y ?: 0.0
        val endLng = startCoordinates?.x ?: 0.0

        val latLng = LocationUtil.getInstance().getCurrentLoc()
        val lastLat = latLng?.latitude ?: 0.0
        val lastLng = latLng?.longitude ?: 0.0
        val r = 6378137
        val dLat = (endLat - lastLat) * Math.PI / 180
        val dLng = (endLng - lastLng) * Math.PI / 180

        val a =
            sin(dLat / 2) * sin(dLat / 2) + cos(lastLat * Math.PI / 180) * cos(endLat * Math.PI / 180) * sin(
                dLng / 2
            ) * sin(dLng / 2)
        val c = 2 * atan2(sqrt(a), sqrt(1 - a))
        val d = r * c

        return getString(R.string.distance, format("%.1f", d / 1000))

    }

    fun speakText(text: String) {
        //播报类型和播报文字回调
        if (mTextToSpeech != null && !TextUtils.isEmpty(text)) {
            /*
                TextToSpeech的speak方法有两个重载。
                // 执行朗读的方法
                speak(CharSequence text,int queueMode,Bundle params,String utteranceId);
                // 将朗读的的声音记录成音频文件
                synthesizeToFile(CharSequence text,Bundle params,File file,String utteranceId);
                第二个参数queueMode用于指定发音队列模式，两种模式选择
                （1）TextToSpeech.QUEUE_FLUSH：该模式下在有新任务时候会清除当前语音任务，执行新的语音任务
                （2）TextToSpeech.QUEUE_ADD：该模式下会把新的语音任务放到语音任务之后，
                等前面的语音任务执行完了才会执行新的语音任务
             */
            Log.e(TAG, "speakText:" + text + "-----------------")
            mTextToSpeech?.speak(text, TextToSpeech.QUEUE_ADD, null);
        }

    }

    fun currentPage(checkedId: Int) {
        binding.layoutTab.groupTab.check(checkedId)
    }

    private fun selectPage(checkedId: Int) {
        var drawable = resources.getDrawable(R.drawable.image_line)
        // 这一步必须要做，否则不会显示。
        drawable.setBounds(
            0, 0, drawable.getMinimumWidth(),
            drawable.getMinimumHeight()
        );

        when (checkedId) {
            R.id.order_record -> {
                binding.viewPager.currentItem = 0
                (fragments[0] as OrderRecordFragment).updateUI()
                binding.appbar.title.text = getString(R.string.driver_order_list)
                binding.layoutTab.ivOne.visibility = View.VISIBLE;
                binding.layoutTab.ivTwo.visibility = View.INVISIBLE;
                binding.layoutTab.ivThree.visibility = View.INVISIBLE;

            }
            R.id.order_receive -> {
                binding.viewPager.currentItem = 1
                (fragments[1] as OrderReceiveFragment).updateUI()
                binding.appbar.title.text = getString(R.string.driver_receive)
                binding.layoutTab.ivOne.visibility = View.INVISIBLE;
                binding.layoutTab.ivTwo.visibility = View.VISIBLE;
                binding.layoutTab.ivThree.visibility = View.INVISIBLE;

            }
            R.id.order_progress -> {
                binding.viewPager.currentItem = 2
                (fragments[2] as OrderInProgressFragment).updateUI()
                binding.appbar.title.text = getString(R.string.driver_main_title)
                binding.layoutTab.ivOne.visibility = View.INVISIBLE;
                binding.layoutTab.ivTwo.visibility = View.INVISIBLE;
                binding.layoutTab.ivThree.visibility = View.VISIBLE;


            }
        }
    }


    companion object {
        const val REQUEST_CODE_GPS_CODE = 0x001
    }

    private var receiver: OrderReceiver? = null

    private var isSee: Boolean = false

    override fun onResume() {
        isSee = true;
        if (receiver == null) {
            receiver = OrderReceiver()
        }
        receiver?.setOrderStateChangeListener(this)
        val filter = IntentFilter(SharedConfig.DRIVER_NEW_ORDER)
        val filter2 = IntentFilter(SharedConfig.REFUSAL_ORDER)
        val filter3 = IntentFilter(SharedConfig.DRIVER_BREAK)
        //注册BroadcastReceiver
        registerReceiver(receiver, filter)
        registerReceiver(receiver, filter2)
        registerReceiver(receiver, filter3)
        super.onResume()
    }

    override fun onPause() {
        super.onPause()
        isSee = false;
    }

    override fun onDestroy() {
        super.onDestroy()
        unregisterReceiver(receiver)
        stopLocationUpdate()
        if (mTextToSpeech != null) {
            // 不管是否正在朗读TTS都被打断
            mTextToSpeech?.stop()
            // 关闭，释放资源
            mTextToSpeech?.shutdown()
            mTextToSpeech = null
        }
    }


    override fun stateChange(intent: Intent?) {
        val action = intent?.action
        val orderId = intent?.getStringExtra("orderId")
        if (action.equals(SharedConfig.DRIVER_NEW_ORDER)) {//新订单
            // playOrderTip()
            orderId?.let { viewModel?.getOrderTemplate(it) }
            (fragments[1] as OrderReceiveFragment).updateUI()
        } else if (action.equals(SharedConfig.REFUSAL_ORDER)) {//司机拒绝订单
            (fragments[1] as OrderReceiveFragment).updateUI()
            (fragments[2] as OrderInProgressFragment).updateUI()
        } else if (action.equals(SharedConfig.DRIVER_BREAK)) {

            AppAlertDialog(this).setContent(getString(R.string.driver_break_msg))
                .setNavigation("", null, false)
                .setPositive(getString(
                    R.string.agree
                ),
                    View.OnClickListener {
                        finish()
                    }).show()

        }
    }


    private fun playOrderTip() {
        //MediaPlayer
        val mediaPlayer = MediaPlayer()
        //准备
        mediaPlayer.setOnPreparedListener {
            mediaPlayer.start()
        }
        try {
            //关键方法：需要设置播放的路径Uri
            val fileDescriptor = resources.assets.openFd("driver_order_tip.mp3")
            mediaPlayer.setDataSource(
                fileDescriptor.fileDescriptor,
                fileDescriptor.startOffset,
                fileDescriptor.length
            )
            mediaPlayer.prepareAsync()
        } catch (e: Exception) {
            L.d("e :$e")
        }
    }

    /**
     * 设置语言类型 为粤语
     */
    override fun onInit(status: Int) {

        if (status === TextToSpeech.SUCCESS) { /*
                使用的是小米手机进行测试，打开设置，在系统和设备列表项中找到更多设置，
            点击进入更多设置，在点击进入语言和输入法，见语言项列表，点击文字转语音（TTS）输出，
            首选引擎项有三项为Pico TTs，科大讯飞语音引擎3.0，度秘语音引擎3.0。其中Pico TTS不支持
            中文语言状态。其他两项支持中文。选择科大讯飞语音引擎3.0。进行测试。

                如果自己的测试机里面没有可以读取中文的引擎，
            那么不要紧，我在该Module包中放了一个科大讯飞语音引擎3.0.apk，将该引擎进行安装后，进入到
            系统设置中，找到文字转语音（TTS）输出，将引擎修改为科大讯飞语音引擎3.0即可。重新启动测试
            Demo即可体验到文字转中文语言。
             */
// setLanguage设置语言
            val result = mTextToSpeech!!.setLanguage(Locale(YUE, HKG))
            // TextToSpeech.LANG_MISSING_DATA：表示语言的数据丢失
// TextToSpeech.LANG_NOT_SUPPORTED：不支持
            if (result == TextToSpeech.LANG_MISSING_DATA
                || result == TextToSpeech.LANG_NOT_SUPPORTED
            ) {
//                Toast.makeText(this, "数据丢失或不支持", Toast.LENGTH_SHORT).show()
            }
        }
    }


}
